package com.jindy.module.repairrecord.service.impl;

import com.jindy.common.core.domain.model.LoginUser;
import com.jindy.common.exception.base.BaseException;
import com.jindy.common.utils.DateUtils;
import com.jindy.common.utils.SecurityUtils;
import com.jindy.common.utils.StringUtils;
import com.jindy.jpush.domain.UniPushDomain;
import com.jindy.jpush.utils.UniJpushUtils;
import com.jindy.module.assistmaterials.domain.AssistMaterials;
import com.jindy.module.assistmaterials.mapper.AssistMaterialsMapper;
import com.jindy.module.constant.StatusConstants;
import com.jindy.module.jpush.mapper.JpushMapper;
import com.jindy.module.machine.domain.Machine;
import com.jindy.module.machine.domain.MachineRecord;
import com.jindy.module.machine.mapper.MachineMapper;
import com.jindy.module.machine.mapper.MachineRecordMapper;
import com.jindy.module.repairMachine.domain.RepairMachine;
import com.jindy.module.repairMachine.mapper.RepairMachineMapper;
import com.jindy.module.repairrecord.domain.RepairRecord;
import com.jindy.module.repairrecord.mapper.RepairRecordMapper;
import com.jindy.module.repairrecord.service.IRepairRecordService;
import com.jindy.module.stock.domain.Stock;
import com.jindy.module.stock.mapper.StockMapper;
import javafx.util.converter.ShortStringConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 机器维修记录Service业务层处理
 *
 * @author ruoyi
 * @date 2022-10-24
 */
@Service
public class RepairRecordServiceImpl implements IRepairRecordService
{
    private static final Logger LOGGER = LoggerFactory.getLogger(RepairRecordServiceImpl.class);
    @Resource
    private RepairRecordMapper repairRecordMapper;
    @Resource
    private MachineMapper machineMapper;
    @Resource
    private AssistMaterialsMapper assistMaterialsMapper;
    @Resource
    private StockMapper stockMapper;
    @Resource
    private RepairMachineMapper repairMachineMapper;
    @Resource
    private MachineRecordMapper machineRecordMapper;

    /**
     * 消息通知设备信息表
     */
    @Resource
    private JpushMapper jpushMapper;

    /**
     * 查询机器维修记录
     *
     * @param id 机器维修记录主键
     * @return 机器维修记录
     */
    @Override
    public RepairRecord selectRepairRecordById(Long id)
    {
        RepairRecord repairRecord = repairRecordMapper.selectRepairRecordById(id);

        //加辅材表
        AssistMaterials assistMaterials = new AssistMaterials();
        assistMaterials.setRepairRecordId(id);
        List<AssistMaterials> assistMaterialsList = assistMaterialsMapper.selectAssistMaterialsList(assistMaterials);
        repairRecord.setAssistMaterialsList(assistMaterialsList);

        //查询报修机器
        selectRepairMachine(repairRecord);
        return repairRecord;
    }

    /**
     * 查询机器维修记录列表
     *
     * @param repairRecord 机器维修记录
     * @return 机器维修记录
     */
    @Override
    public List<RepairRecord> selectRepairRecordList(RepairRecord repairRecord)
    {
        //获取当前登录人
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (Objects.isNull(loginUser)){
            throw new BaseException("查询【机器维修】列表-请先登录");
        }
        Long loginUserUserId = loginUser.getUserId();
        if (loginUserUserId.equals(1L)){
            loginUserUserId=null;
        }
        List<RepairRecord> repairRecordList = repairRecordMapper.selectRepairRecordList(loginUserUserId,repairRecord);
        //加辅材表
        if(!CollectionUtils.isEmpty(repairRecordList)){
            repairRecordList.forEach(record->{
                AssistMaterials assistMaterials = new AssistMaterials();
                assistMaterials.setRepairRecordId(record.getId());
                List<AssistMaterials> assistMaterialsList = assistMaterialsMapper.selectAssistMaterialsList(assistMaterials);
                record.setAssistMaterialsList(assistMaterialsList);
                //加报修机器
                selectRepairMachine(record);
            });
        }

        return repairRecordList;
    }
    /**
     * 查询报修机器
     *
     * @param repairRecord 机器维修记录
     * @return 结果
     */
    void selectRepairMachine(RepairRecord repairRecord){
        RepairMachine repairMachine = new RepairMachine();
        repairMachine.setRepairRecordId(repairRecord.getId());
        List<RepairMachine> repairMachineList = repairMachineMapper.selectRepairMachineList(repairMachine);
        repairRecord.setRepairMachineList(repairMachineList);
    }

    /**
     * 根据传入的机器编号查询其所有的机器维修记录列表
     *
     * @param repairRecord 机器维修记录
     * @return 机器维修记录集合
     */
    @Override
    public List<RepairRecord> selectRepairRecordList2(RepairRecord repairRecord) {
        List<RepairRecord> list = new ArrayList<>();
        if (repairRecord != null && StringUtils.isNotBlank(repairRecord.getMachineNo())) {
            // 使用Optional对象避免空指针异常
            Optional<String> machineNoOptional = Optional.ofNullable(repairRecord.getMachineNo());
            // 将machineNo转换为RepairMachine对象
            RepairMachine repairMachine = machineNoOptional.filter(StringUtils::isNotBlank)
                    .map(machineNo -> {
                        RepairMachine machine = new RepairMachine();
                        machine.setMachineNo(machineNo);
                        return machine;
                    }).orElse(new RepairMachine());
            // 查询对应的维修机器列表
            List<RepairRecord> recordList = repairMachineMapper.selectRepairMachineList(repairMachine).stream()
                    .map(RepairMachine::getRepairRecordId)
                    .flatMap(repairRecordId -> Optional.ofNullable(repairRecordMapper.selectRepairRecordById(repairRecordId))
                            .map(Stream::of).orElseGet(Stream::empty))
                    .collect(Collectors.toList());
            list.addAll(recordList);
        }
        return list;
    }

    private List<RepairRecord> selectRepairRecordList3(RepairRecord repairRecord) {
        List<RepairRecord> list = new ArrayList<>();
        //根据传入的机器编号，查出所有的维修机器
        if (repairRecord != null && StringUtils.isNotBlank(repairRecord.getMachineNo())) {
            List<RepairMachine> machineList = Optional.ofNullable(repairRecord.getMachineNo())
                    .filter(StringUtils::isNotBlank)
                    .map(machineNo -> {
                        RepairMachine repairMachine = new RepairMachine();
                        repairMachine.setMachineNo(machineNo);
                        return repairMachineMapper.selectRepairMachineList(repairMachine);
                    })
                    .orElse(Collections.emptyList());
            //根据维修机器获取所有的维修单
            if(!CollectionUtils.isEmpty(machineList)){
                machineList.forEach(machine->{
                    RepairRecord repairRecord1 = repairRecordMapper.selectRepairRecordById(machine.getRepairRecordId());
                    if(repairRecord1 != null){
                        list.add(repairRecord1);
                    }
                });
            }
        }
        return list;
    }




    /**
     * 新增机器维修记录
     *
     * @param repairRecord 机器维修记录
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertRepairRecord(RepairRecord repairRecord)
    {

        //新增机器维修记录
        repairRecord.setCreateTime(DateUtils.getNowDate());
        repairRecord.setAuditState("0");
        int result = repairRecordMapper.insertRepairRecord(repairRecord);

        if(!CollectionUtils.isEmpty(repairRecord.getRepairMachineList())){
            for(RepairMachine machine1 : repairRecord.getRepairMachineList()){
                //如果是仓库内的报修，则需要修改可用库存,一次报修一台机器,项目上则不用
                if("0".equals(machine1.getStatus())){
                    Stock stock = new Stock();
                    stock.setModel(machine1.getModel());
                    stock.setWarehouseId(machine1.getWarehouseId());
                    List<Stock> stockList = stockMapper.selectStockList(stock);
                    if(!CollectionUtils.isEmpty(stockList)){
                        Stock stock1 = stockList.get(0);
                        stock1.setAvailableQuantity(stock1.getAvailableQuantity()-1);//可用库存-1
                        stockMapper.updateStock(stock1);
                    }
                }

                //如果是项目上报修，则要判断机器和报修单是否属于一个租赁订单
                if("2".equals(machine1.getStatus())){
                    MachineRecord machineRecord = new MachineRecord();
                    machineRecord.setOrderId(repairRecord.getOrderId());
                    machineRecord.setMachineNo(machine1.getMachineNo());
                    List<MachineRecord> machineRecordList = machineRecordMapper.selectMachineRecordList(machineRecord);
                    if(CollectionUtils.isEmpty(machineRecordList)){
                        throw new RuntimeException("机器序列号为：" + machine1.getMachineSerialNumber() + " 的机器不属于此租赁订单！");
                    }
                }

                //修改机器状态为"1"，不可用
                Machine machine = new Machine();
                machine.setMachineNo(machine1.getMachineNo());
                List<Machine> machineList = machineMapper.selectMachineList(machine);
                if(!CollectionUtils.isEmpty(machineList)){
                    Machine machine2 = machineList.get(0);
                    machine2.setStatus(StatusConstants.MachineStatusConstant.machineStatus_1);
                    machineMapper.updateMachine(machine2);
                }
            }
        }

        //新增维修辅材列表
        if(!CollectionUtils.isEmpty(repairRecord.getAssistMaterialsList())){
            repairRecord.getAssistMaterialsList().forEach(assistMaterials ->{
                assistMaterials.setRepairRecordId(repairRecord.getId());
                assistMaterialsMapper.insertAssistMaterials(assistMaterials);
            });
        }
        //新增维修机器列表
        if(!CollectionUtils.isEmpty(repairRecord.getRepairMachineList())){
            repairRecord.getRepairMachineList().forEach(machine->{
                machine.setRepairRecordId(repairRecord.getId());
                repairMachineMapper.insertRepairMachine(machine);
            });
    }
        //通知业务员
        sendMessageToSalesman(repairRecord);
        return result;
    }

    /**
     * 通知业务员
     * @param repairRecord
     */
    private void sendMessageToSalesman(RepairRecord repairRecord) {
        try {
            List<String> addRegIds = jpushMapper.selectRegistrationIdsByUserIds(Collections.singletonList(repairRecord.getSalesmanId()));
            if (!CollectionUtils.isEmpty(addRegIds)) {
                UniPushDomain uniPushDomain = new UniPushDomain(addRegIds, "湿云", "您有一条新的维修管理单，请查看！");
                UniJpushUtils.doPost(uniPushDomain);
            }else {
                throw new BaseException("业务员设备id未找到");
            }
        } catch (Exception e) {
            LOGGER.error("机器维修发送通知失败",e);
        }
    }


    /**
     * 修改机器维修记录
     *
     * @param repairRecord 机器维修记录
     * @return 结果
     */
    @Override
    public int updateRepairRecord(RepairRecord repairRecord)
    {
        repairRecord.setUpdateTime(DateUtils.getNowDate());

        //先删后增辅材表
        assistMaterialsMapper.deleteAssistMaterialsByRepairRecordId(repairRecord.getId());
        if(!CollectionUtils.isEmpty(repairRecord.getAssistMaterialsList())){
            repairRecord.getAssistMaterialsList().forEach(assistMaterials ->{
                assistMaterials.setRepairRecordId(repairRecord.getId());
                assistMaterialsMapper.insertAssistMaterials(assistMaterials);
            });
        }

        return repairRecordMapper.updateRepairRecord(repairRecord);
    }

    /**
     * 批量删除机器维修记录
     *
     * @param ids 需要删除的机器维修记录主键
     * @return 结果
     */
    @Override
    public int deleteRepairRecordByIds(Long[] ids)
    {
        return repairRecordMapper.deleteRepairRecordByIds(ids);
    }

    /**
     * 删除机器维修记录信息
     *
     * @param id 机器维修记录主键
     * @return 结果
     */
    @Override
    public int deleteRepairRecordById(Long id)
    {
        return repairRecordMapper.deleteRepairRecordById(id);
    }

}
